<template>
  <span ref="targetRef" class="rolling-numbers"></span>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, nextTick } from 'vue';
import gsap from 'gsap';

const props = defineProps({
  value: {
    type: String,
    required: true,
  },
  duration: {
    type: Number,
    default: 1.5,
  },
  ease: {
    type: String,
    default: 'power4.out',
  },
  delay: {
    type: Number,
    default: 0,
  },
});

const targetRef = ref<HTMLElement | null>(null);
let animationInstances: gsap.core.Tween[] = [];

// 生成数字滚动序列 (0-9循环)
const generateNumberSequence = (target: string) => {
  const num = parseInt(target);
  return Array.from({ length: 10 }, (_, i) =>
    String((num + i + 1) % 10),
  ).reverse(); // [target+1, target+2,...,9,0,1,...,target]
};

// 清理旧动画和元素
const cleanup = () => {
  animationInstances.forEach(anim => anim.kill());
  animationInstances = [];
  if (targetRef.value) {
    targetRef.value.innerHTML = '';
  }
};

// 创建滚动元素
const createRollingElement = (char: string) => {
  if (!/\d/.test(char)) {
    const span = document.createElement('span');
    span.textContent = char;
    return span;
  }

  const wrapper = document.createElement('div');
  wrapper.className = 'digit-wrapper';
  wrapper.style.display = 'inline-block';
  wrapper.style.overflow = 'hidden';
  wrapper.style.verticalAlign = 'top';

  const container = document.createElement('div');
  container.className = 'digit-container';

  const numbers = generateNumberSequence(char);
  numbers.forEach(num => {
    const div = document.createElement('div');
    div.className = 'digit';
    div.textContent = num;
    container.appendChild(div);
  });

  // 设置初始位置
  const targetIndex = numbers.indexOf(char);
  container.style.transform = `translateY(${-targetIndex * 100}%)`;

  wrapper.appendChild(container);
  return wrapper;
};

// 初始化动画
const setupAnimation = () => {
  cleanup();
  if (!targetRef.value) return;

  Array.from(props.value).forEach((char, index) => {
    const element = createRollingElement(char);
    targetRef.value?.appendChild(element);

    if (element.classList.contains('digit-wrapper')) {
      const container = element.querySelector(
        '.digit-container',
      ) as HTMLElement;
      const targetY = 0;
      const anim = gsap.fromTo(
        container,
        { y: container.style.transform },
        {
          y: targetY + '%',
          duration: props.duration,
          ease: props.ease,
          delay: index * 0.1 + props.delay,
        },
      );
      animationInstances.push(anim);
    }
  });
};

watch(
  () => props.value,
  () => {
    nextTick(() => setupAnimation());
  },
);

onMounted(() => {
  nextTick(() => setupAnimation());
});
</script>

<style scoped>
.rolling-numbers {
  display: inline-block;
  font-family: monospace; /* 保证数字等宽 */
}

.digit-wrapper {
  height: 1em;
  line-height: 1em;
}

.digit-container {
  transition: transform 0.5s ease-out;
}

.digit {
  height: 1em;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
